<?php
/* MyMeeting is an online meeting management software.
 * Copyright (C) 2009 Government Of Malaysia
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * @author: Abdullah Zainul Abidin, Nuhaa All Bakry
 *          Eavay Javay Barnad, Sarogini Muniyandi, Teow Jit Huan
 *
 */

class UsersController extends AppController {

    /**
     * Define $name
     *
     */
    var $name = 'Users';
    /**
     * Define $helpers
     *
     */
    var $helpers = array('Html', 'Form', 'Crumb','Javascript');
    /**
     * Define $uses
     *
     */
    var $uses = array('User', 'Committee','Notification','Template','Hash');

    /**
     * Define $paginate
     *
     */
    var $paginate = array(
        //'limit' => '4',
        'order'=>array(
            'User.protocol_id'=>'asc'
        )
    );

    /**
     * Describe captcha
     *
     * @return null
     */
    function captcha(){
        App::import('vendor','captcha');
        $captcha = new CaptchaSecurityImages();
        $code=$captcha->render();
        $this->Session->write('securitycode',$code);
        $this->writelog(get_class($this),__FUNCTION__,"Captcha code $code generated  ");
    }


    /**
     * Describe changepassword
     *
     * @return null
     */
    function changepassword(){
        //$this->layout='mainpage';
        if (!empty($this->data)) {
            $someone = $this->User->findById($this->Auth->user('id'));
            if(($this->Auth->password($this->data['User']['oldpassword'])) != $someone['User']['password']) {
                $this->Session->setFlash(__('Your old password is invalid.', true));
            }
            elseif($this->data['User']['password'] !=$this->data['User']['confirmpassword']){
                $this->Session->setFlash(__('Your password does not match.', true));
            } else {

                $this->data['User']['id'] = $this->Auth->user('id');
                $this->data['User']['password'] = $this->Auth->password($this->data['User']['password']);
                if ($this->User->save($this->data,false)){
                    $this->Session->setFlash(__('Your password has been changed',true));
                    $this->redirect(array('action'=>'profile'));
                }
            }
        }
    }

    function resetpass($id = null,$comm =null) {
        $this->data['User']['id'] = $id;
        $someone = $this->User->findById($id);
        $someone['User']['password'] = $this->Auth->password($someone['User']['username']);
        $someone['User']['locked'] =null;
        if ($this->User->save($someone,false)){
            $someone['User']['newpassword'] = $someone['User']['username']; 
            $t = $this->Template->find('first',array('conditions'=>array('type'=>'reset password','model'=>'SystemOnly')));
            $this->User->Meeting->sendEmail(null,$t,$someone['User'],null);
            $this->Session->setFlash(sprintf(__('Password for %s has been reset and emailed',true),$someone['User']['username']));
            if(!empty($comm)){
                $this->redirect(array('committee'=>$comm,'controller'=>'memberships','action'=>'index'));
            }
            $this->redirect(array('action'=>'index'));
        }
    }

    function forcechangepassword() {
        
        if (!empty($this->data)) {
            if ($this->data['User']['password'] !=$this->data['User']['confirmpassword']){
                $this->Session->setFlash(__('Your password does not match.', true));
            } else {
                $this->data['User']['id'] = $this->Auth->user('id');
                $this->data['User']['password'] = $this->Auth->password($this->data['User']['password']);
                if ($this->User->save($this->data,false)){
                    $this->Session->setFlash(__('Your password has been changed',true));
                    $this->Session->write('haschanged','Y');
                    $this->writelog(get_class($this),__FUNCTION__,"Password changed. Session haschanged=Y");
                    if ($this->Session->check('lastvisitedpage') && $this->Session->read('lastvisitedpage')!='users/forcechangepassword') { // if user not coming from root url
                        $this->redirect(Configure::read('server_url').'/'.$this->Session->read('lastvisitedpage'));
                        $this->Session->del('lastvisitedpage');
                    } else {
                        $this->redirect(array('action'=>'mainpage','controller'=>'committees'));
                    }
                }
            }
        }
    }


    function haschangedpassword() {
       $this->writelog(get_class($this),__FUNCTION__,"LOGGED IN");
       $this->User->unbindModel(array('hasMany'=>array('Announcement','Meetingtodo','Groupstatus','Log')),false);   
       $user = $this->User->findById($this->Auth->user('id'));
        if ($this->Auth->password($this->Auth->user('username')) == $user['User']['password']) {
            $this->Session->write('haschanged','N');
            $this->writelog(get_class($this),__FUNCTION__,"User has NOT changed password. Session haschanged=N");
            $this->redirect(array('action'=>'forcechangepassword'));
        } else {
            $this->Session->write('haschanged','Y');
            $this->writelog(get_class($this),__FUNCTION__,"User has changed password. Session haschanged=Y");
            if ($this->Session->check('lastvisitedpage')) {
                 // if user not coming from root url
                $this->redirect(Configure::read('server_url').'/'.$this->Session->read('lastvisitedpage'));
            } else {
                $this->redirect(array('action'=>'mainpage','controller'=>'committees'));
            }
        }
    }

    function checkcaptcha() {
        $this->pageTitle = __("Login",true);
        $this->set('displaycaptcha',1);

    }

    /**
     * Describe login
     *
     * @return null
     */
    function login(){
       if(!($this->User->find('count')) ){
            $this->redirect(array('controller'=>'installers','action'=>'install'));
        }
        $this->pageTitle = __("Login",true);
        $this->set('displaycaptcha',0);

        if (!empty($this->data['User'])) {
            $this->writelog(get_class($this),__FUNCTION__,$this->data['User']['username']." is trying to login");
            $this->Session->write('trylogin',$this->Session->read('trylogin')+1);

            if(!$this->Auth->user('id')){ // wrong username/password
                $this->Session->SetFlash(__('Invalid username or password',true));
                
                //Check whether the account is locked
                $this->User->recursive=-1;
                $duser=$this->User->find('first',array('conditions'=>array('username'=>$this->data['User']['username'])));
                if(!empty($duser) && date('Y-m-d H:i:s',strtotime($duser['User']['locked']))>date('Y-m-d H:i:s')){
                    $this->Session->SetFlash(__('Your account is locked, please contact admin or secretariat to reset your password',true));
                }
                
                $this->writelog(get_class($this),__FUNCTION__,"Failed attempt to login no. ".$this->Session->read('trylogin')." with username: ".$this->data['User']['username']);
                
                if ($this->Session->read('trylogin') > 6) {
                    if(!empty($duser)){
                        $duser['User']['locked']=date('Y-m-d H:i:s',mktime(date("H")+1,date("i"),date("s"),date("m"),date("d"),date("Y")));
                        $this->User->save($duser);
                        $this->Session->SetFlash(__('Your account is locked, please contact admin or secretariat to reset your password',true));
                    }
                }elseif ($this->Session->read('trylogin') > 3) {
                    $this->set('displaycaptcha',1);
                    $this->writelog(get_class($this),__FUNCTION__,"Displaying CAPTCHA for ".$this->data['User']['username']);
                } else {
                    $this->set('displaycaptcha',0);
                }
            }
        } else {

            // if user needs to enter captcha value
            if ($this->Auth->user('id')) {
                $this->set('displaycaptcha',1);
                $this->writelog(get_class($this),__FUNCTION__,"Displaying CAPTCHA for ".$this->Auth->user('id'));
            } else {
                $this->Session->write('trylogin',0);
                $this->Session->delete('securitycode');
            }
        }
    }

    /**
     * Describe logout
     *
     * @return null
     */
    function logout(){

        $this->Auth->logout();
        $this->writelog(get_class($this),__FUNCTION__,"LOGGED OUT");

        $this->Session->delete('haschanged');
        $this->Session->delete('lastvisitedpage');
        $this->Session->delete('history');
        $this->Session->delete('trylogin');
        $this->Session->delete('login_username');
        $this->Session->delete('login_captcha');
        $this->Session->delete('permission');
        $this->Session->SetFlash(__('Successfully logged out',true));
        //unset($_SESSION['Message']['flash']['message']);

        //$this->redirect($this->Auth->redirect());
        $this->redirect(array('action'=>'login'));
    }

    /**
     * Describe index
     *
     * @return null
     */
    function index() {
        $this->User->unbindmodel(array('hasMany'=>array('Announcement','Meetingtodo','Userstatus','Groupstatus'),'hasAndBelongsToMany'=>array('Committee','Meeting','Decision','Group')),false);
        // if resetting password
        if(isset($this->params['pass']['1']) && $this->params['pass']['1']=='reset') $this->_resetpass($this->params['pass']['0']);

        // first page
        if (empty($this->params['named']['page']) || empty($this->data)) {
            $this->Session->delete('Search.username');
            $this->Session->delete('Search.committee');
            $this->Session->delete('Search.name');
            $this->Session->delete('Search.job_title');
            $this->Session->delete('Search.email');
        }

        // get the search terms
        if(!empty($this->data['Search']['username'])) $cursearch_user = $this->data['Search']['username'];
        elseif($this->Session->check('Search.username')) $cursearch_user = $this->Session->read('Search.username');
        else $cursearch_user = '';

        if(!empty($this->data['Search']['committee'])) $cursearch_comm = $this->data['Search']['committee'];
        elseif($this->Session->check('Search.committee')) $cursearch_comm = $this->Session->read('Search.committee');
        else $cursearch_comm = '';

        if(!empty($this->data['Search']['name'])) $cursearch_name = $this->data['Search']['name'];
        elseif($this->Session->check('Search.name')) $cursearch_name = $this->Session->read('Search.name');
        else $cursearch_name = '';

        if(!empty($this->data['Search']['job_title'])) $cursearch_job = $this->data['Search']['job_title'];
        elseif($this->Session->check('Search.job_title')) $cursearch_job = $this->Session->read('Search.job_title');
        else $cursearch_job = '';

        if(!empty($this->data['Search']['email'])) $cursearch_email = $this->data['Search']['email'];
        elseif($this->Session->check('Search.email')) $cursearch_email = $this->Session->read('Search.email');
        else $cursearch_email = '';

        // construct queries
        $filters = array();
        if(isset($cursearch_user) && $cursearch_user!='') {
            array_push($filters,"User.username  like '%".$cursearch_user."%'");
            //$filters['User.username'] = 'LIKE %'.$cursearch_user.'%';
            $this->Session->write('Search.username', $cursearch_user);
        }
        if(isset($cursearch_comm) && $cursearch_comm!='') {
            //$filters = array("Committee.id ='".$cursearch_comm."'")
            $percommittee = $this->User->getUsersPerCommittee($cursearch_comm);
            $percommittee = Set::extract('/User/id',$percommittee);
            $filters['User.id'] = $percommittee;
            $this->Session->write('Search.committee', $cursearch_comm);
        }
        if(isset($cursearch_name) && $cursearch_name!='') {
            array_push($filters,"User.name  like '%".$cursearch_name."%'");
            //$filters['User.name'] = 'LIKE %'.$cursearch_name.'%';
            $this->Session->write('Search.name', $cursearch_name);
        }
        if(isset($cursearch_job) && $cursearch_job!='') {
            array_push($filters,"User.job_title  like '%".$cursearch_job."%'");
            //$filters['User.job_title'] = 'LIKE %'.$cursearch_job.'%';
            $this->Session->write('Search.job_title', $cursearch_job);
        }
        if(isset($cursearch_email) && $cursearch_email!='') {
            array_push($filters,"User.email  like '%".$cursearch_email."%'");
            //$filters['User.email'] = 'LIKE %'.$cursearch_email.'%';
            $this->Session->write('Search.email', $cursearch_email);
        }
        $filters['User.deleted'] = '0';
        $this->set('users', $this->paginate('User', $filters));

        // for searchbox
        $committee = $this->Committee->find('list',array('order'=>'Committee.short_name ASC'));
        $this->set('committee',$committee);
    }

    /**
     * Describe view
     *
     * @param $id
     * @return null
     */
    function view($id = null) {
        $this->User->unbindmodel(array('hasMany'=>array('Announcement','Meetingtodo','Userstatus','Groupstatus'),'hasAndBelongsToMany'=>array('Meeting','Decision','Group')),false);
        //$this->layout='mainpage';
        if (!$id) {
            $this->Session->setFlash(__('Invalid User.', true));
            $this->redirect(array('action'=>'index'));
        }
        $this->set('user', $this->User->find(array('User.id'=>$id)));
    }

    /**
     * Describe add
     *
     * @return null
     */
    function add() {
        //$this->layout='mainpage';
        if (!empty($this->data)) {
            $password=$this->data['User']['password'];
            if ($this->data['User']['password'] == $this->Auth->password($this->data['User']['password_confirm'])) {
                $this->User->create();
                //debug($this->data);
                if ($this->User->save($this->data)) {
                    if(!empty($this->data['Committee']['Committee'])){
                        $this->User->Membership->saveRoles($this->data['Committee']['Committee'],array(),$this->User->getLastInsertID());
                    }
                    $this->Session->setFlash(__('The User has been saved', true));
                    $this->redirect(array('action'=>'index'));
                } else {
                    $this->data['User']['password'] =$this->data['User']['password_confirm'];
                    $this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
                }
            } else {
                $this->data['User']['password'] ='';
                $this->data['User']['password_confirm'] ='';
                $this->Session->setFlash(__('The User could not be created. Password are not identical.', true));
            }
        }
        $committees = $this->User->Committee->find('list');
        $meetings = $this->User->Meeting->find('list');
        $groups = $this->User->Group->find('list');
        $titles = $this->User->Title->find('list');
        $protocols = $this->User->Protocol->find('list',array('order'=>'Protocol.rank Asc'));
        $schemes = $this->User->Scheme->find('list',array('order'=>'Scheme.name Asc'));
        $this->set(compact('committees', 'meetings', 'groups', 'titles','protocols','schemes'));
    }

    /**
     * Describe edit
     *
     * @param $id
     * @return null
     */
    function edit($id = null) {
        //$this->layout='mainpage';
        if (!$id && empty($this->data)) {
            $this->Session->setFlash(__('Invalid User', true));
            $this->redirect(array('action'=>'index'));
        }
        if (!empty($this->data) && !empty($this->data['Committee']['Committee'])) {
            // get user roles in each committee before saving - skipping this will reset user roles in membership (HABTM)
            $old_membership = $this->User->Membership->find('all',array('conditions'=>array('Membership.committee_id'=>$this->data['Committee']['Committee'],'user_id'=>$id),'fields'=>'Membership.*'));
            $oldie=array();
            foreach ($old_membership as $old) {
                $oldie[$old['Membership']['committee_id']] = $old['Membership']['role_id'];
            }

            if ($this->User->save($this->data)) {
                // save user roles in membership
                if ($this->data['Committee']['Committee']!='')
                $this->User->Membership->saveRoles($this->data['Committee']['Committee'],$oldie,$id);

                $this->Session->setFlash(__('The User has been saved', true));
                $this->redirect('index');
            } else {
                $this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
            }
        }
        elseif (!empty($this->data) && empty($this->data['Committee']['Committee'])){
            if ($this->User->save($this->data)) {
                $this->Session->setFlash(__('The User has been saved', true));
                $this->redirect('index');
            } else {
                $this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
            }
        }
        if (empty($this->data)) {
            $this->data = $this->User->read(null, $id);
        }
        $committees = $this->User->Membership->Committee->find('list');
        $titles = $this->User->Title->find('list');
        $protocols = $this->User->Protocol->find('list',array('order'=>'Protocol.rank Asc'));
        $schemes = $this->User->Scheme->find('list',array('order'=>'Scheme.name Asc'));
        $this->set(compact('committees','titles','protocols','schemes'));
    }

    /**
     * Describe profile
     *
     * @return null
     */
    function profile() {
        $this->User->recursive=-1;
        if (!$this->Auth->user('id')) {
            $this->Session->setFlash(__('Invalid User', true));
            $this->redirect(array('action'=>'index'));
        }
        if (!empty($this->data)) {
            if ($this->User->save($this->data)) {
                $this->Session->setFlash(__('The profile has been saved', true));
                $this->redirect(array('controller'=>'committees','action'=>'mainpage'));
            } else {
                $this->Session->setFlash(__('The profile could not be saved. Please, try again.', true));
            }
        }
        //if (empty($this->data)) {
            $this->data = $this->User->read(null, $this->Auth->user('id'));
        //}
        $titles = $this->User->Title->find('list');
        $protocols = $this->User->Protocol->find('list',array('order'=>'Protocol.rank Asc'));
        $schemes = $this->User->Scheme->find('list',array('order'=>'Scheme.name Asc'));
        $this->set(compact('titles','protocols','schemes'));
        $this->set('data',$this->data);
    }

    /**
     * Describe delete
     *
     * @param $id
     * @return null
     */
    function delete($id = null) {
        if (!$id) {
            $this->Session->setFlash(__('Invalid id for User', true));
            $this->redirect(array('action'=>'index'));
        }
        $this->User->delete($id);
        $this->Session->setFlash(__('User deleted', true));
        $this->redirect(array('action'=>'index'));
    }

    function forgotpass() {
        if (!empty($this->data)) {
            $this->User->Behaviors->attach('Containable');
            $user = $this->User->find('first',array('conditions'=>array('email'=>$this->data['User']['email']),'contain'=>array('Title'),'fields'=>'User.*,Title.*'));
            if($user){
                $this->User->createhash($user['User']['id']); 
                $t = $this->Template->find('first',array('conditions'=>array('type'=>'forgot password','model'=>'SystemOnly')));
                if($t){
                    $hash = $this->Hash->find('first',array('conditions'=>array('model'=>'User','foreign_key'=>$user['User']['id'],'hash_type'=>'password'),'fields'=>array('hash'),'order'=>array('Hash.id'=>'desc')));
                    count($hash) ? $data['hash']= $hash['Hash']['hash'] : $data['hash']='';
                    $user['User']['Link']['password']='/hash1/'.$data['hash'];
                    $user['User']['slogan'] = '"'.strtoupper(Configure::read('agency_slogan')).'"'; 
                    $user['User']['due_date']=date('d/m/Y',mktime(date('H'), date('i'), date('s'), date('m'), date('d')+Configure::read('days_to_remind'), date('Y'))); 
                
                    $this->User->Meeting->sendEmail(null,$t,$user['User'],null);
                    $this->Session->setFlash(__('Your request has been generated. Please check your email.', true));
                    $this->redirect(array('action'=>'login'));
                } 
            }else {
                $this->Session->setFlash(__('The email is not registered in the system.', true));
            }
        }
    }

    function forgotuser() {
        if (!empty($this->data)) {
            $this->User->Behaviors->attach('Containable');
            $user = $this->User->find('first',array('conditions'=>array('email'=>$this->data['User']['email']),'contain'=>array('Title'),'fields'=>'User.*,Title.*'));
            if ($user) {
                $user['User']['slogan'] = '"'.strtoupper(Configure::read('agency_slogan')).'"'; 
                $t = $this->Template->find('first',array('conditions'=>array('type'=>'forgot username','model'=>'SystemOnly')));
                $this->User->Meeting->sendEmail(null,$t,$user['User'],null);
                $this->Session->setFlash(__('Your username has been sent to your email.', true));
                $this->redirect(array('action'=>'login'));
            } else {
                $this->Session->setFlash(__('The email is not registered in the system.', true));
            }
        }
    }
}


?>
